/*******************************************************************************
**                                                                            **
** Copyright (C)    (2016)                                               **
**                                                                            **
** All rights reserved.                                                       **
**                                                                            **
** This document contains proprietary information belonging to .         **
** Passing on and copying of this document, and communication                 **
** of its contents is not permitted without prior written authorization.      **
**                                                                            **
********************************************************************************
**                                                                            **
**  FILENAME    : PduR_Internal.c                                             **
**                                                                            **
**  Created on  :                                                             **
**  Author      : zhengfei.li                                                 **
**  Vendor      :                                                             **
**  DESCRIPTION : PDUR internal API definitions                               **
**                                                                            **
**  SPECIFICATION(S) :   AUTOSAR classic Platform 4.2.2                       **
**                                                                            **
*******************************************************************************/
/*******************************************************************************
**                      Includes                                              **
*******************************************************************************/
#include "PduR_Internal.h"
#if(STD_OFF == PDUR_ZERO_COST_OPERATION)
/*******************************************************************************
**                      Private Function Declarations                         **
*******************************************************************************/
#define PDUR_START_SEC_CODE
#include "PduR_MemMap.h"
#if(STD_ON == PDUR_TP_SUPPORT)
/*if the tp buffer which have been copyed all data by all dest Tp Pdus,need clear the tp buffer*/
static FUNC(boolean, PDUR_CODE)
PduR_GateWayOnTheFlyNeedClearTpBuffer(PduIdType SrcPdu,uint8 CopyTpBufferNumber);
/*copy the rx pdu data to the tp buffer*/
static FUNC(BufReq_ReturnType, PDUR_CODE)
PduR_CopyRxTpDataToTpBuffer(uint8 TpBufferId,P2CONST(PduInfoType, AUTOMATIC, PDUR_APPL_DATA) Info,P2VAR(PduLengthType, AUTOMATIC, PDUR_APPL_DATA) BufferSizePtr);
/*find one unused tp buffer.if no unused tp buffer,return 0xff*/
static FUNC(uint8, PDUR_CODE)
PduR_FindNextValidTpBuffer(void);
/*gateway MF pdu to Tp mode by LoTp_Transmit*/
static FUNC(boolean, PDUR_CODE)
PduR_GateWayMFToTp(uint16 PduRSrcPduId,uint16 PduRDestPduId);
/*gateway SF pdu to Tp mode by LoTp_Transmit*/
static FUNC(Std_ReturnType, PDUR_CODE)
PduR_GateWaySFToTp(uint16 PduRSrcPduId,uint16 PduRDestPduId);
/*SF Tp pdu 1:n(n>1) route:route the pdu to one up mode*/
static FUNC(void, PDUR_CODE)
PduR_RouteSFtoUp(uint8 DestModule,uint16 PduRSrcPduId,uint16 PduRDestPduId);
/*MF Tp pdu 1:n(n>1) route:route the pdu to one up mode*/
static FUNC(void, PDUR_CODE)
PduR_RouteMFtoUp(uint8 DestModule,uint16 PduRSrcPduId,uint16 PduRDestPduId);
/*find one valid tp buffer.if not find,return 0xff*/
static FUNC(uint8, PDUR_CODE)
PduR_FindValidTpBuffer(uint16 PduRSrcPduId,uint16 PduLength);
/*find the rx tp pdu active store tp buffer*/
static FUNC(uint8, PDUR_CODE)
PduR_FindTpBuffer(uint16 PduRSrcPduId);
#endif/*STD_ON == PDUR_TP_SUPPORT*/
#define PDUR_STOP_SEC_CODE
#include "PduR_MemMap.h"
/*******************************************************************************
**                      Global Function Definitions                           **
*******************************************************************************/
#define PDUR_START_SEC_CODE
#include "PduR_MemMap.h"
#if(STD_ON == PDUR_TP_SUPPORT)
/*Rx Tp Pdu gateway to only one Tp Module Pdu handle,when start of reception*/
FUNC(BufReq_ReturnType, PDUR_CODE)
PduR_StartOfReceptionToOneTpHandle
(
    PduIdType SrcPduId,
	PduIdType DestPduId,
	P2CONST(PduInfoType, AUTOMATIC, PDUR_APPL_DATA) info,
	PduLengthType Length,
	P2VAR(PduLengthType, AUTOMATIC, PDUR_APPL_DATA) bufferSizePtr
)
{
	BufReq_ReturnType bufQeqReturn = BUFREQ_E_NOT_OK;
	uint8 findTpBuffer = 0xff;
	uint16 pduRDestTxBuffeId;
	PduIdType gatewayTpRunTimeId;
	#if(STD_ON == PDUR_META_DATA_SUPPORT)
	uint8 metaDataLength;
	metaDataLength = PduR_ConfigStd->PduRSrcPduRef[SrcPduId].MetaDataLength;
	#endif
	gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[DestPduId].GateWayTpRunTimeIndex;
	/*MF tp pdu gateway,need store in tp buffer*/
	if(FALSE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].TpPduIsSF)
	{
		/*find one valid tp buffer.if not find,return 0xff*/
		findTpBuffer = PduR_FindValidTpBuffer(SrcPduId,Length);
		/*find the valid tp buffer*/
		if(0xff != findTpBuffer)
		{
			PduR_TpBuffer[findTpBuffer].used = TRUE;
			PduR_TpBuffer[findTpBuffer].RxBufferOffset = 0;
			PduR_TpBuffer[findTpBuffer].SduLength = Length;
			#if(STD_ON == PDUR_META_DATA_SUPPORT)
			PduR_Memcpy(PduR_TpBuffer[findTpBuffer].MetaData,info->SduDataPtr,metaDataLength);
			#endif
			PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId = findTpBuffer;
			PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = FALSE;
			PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = 0;
			/*gateway-on-the-fly*/
			if(TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].GatewayOnTheFly)
			{
				PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly = TRUE;
				PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].CopyCompleteTpBufferNumber = 0;
				if(0 == PduR_ConfigStd->PduRDestPduRef[DestPduId].PduRTpThreshold)
				{
					/*gateway MF pdu to Tp mode by LoTp_Transmit*/
					if(E_NOT_OK == PduR_GateWayMFToTp(SrcPduId,DestPduId))
					{
						PduR_ClearBufferAndStateOfGateWayTpPdu(SrcPduId);
						bufQeqReturn = BUFREQ_E_NOT_OK;
					}
					else
					{
						bufQeqReturn = BUFREQ_OK;
						*bufferSizePtr = PduR_TpBuffer[findTpBuffer].TpBufferLength;
					}
					PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly = FALSE;
				}
				else
				{
					bufQeqReturn = BUFREQ_OK;
					*bufferSizePtr = PduR_TpBuffer[findTpBuffer].TpBufferLength;
				}
			}
			else
			{
				bufQeqReturn = BUFREQ_OK;
				*bufferSizePtr = PduR_TpBuffer[findTpBuffer].TpBufferLength;
			}
		}
		else
		{
			bufQeqReturn = BUFREQ_E_OVFL;
		}
	}
	/*SF tp pdu gateway,need store in dedicated buffer*/
	else
	{
		pduRDestTxBuffeId = PduR_ConfigStd->PduRDestPduRef[DestPduId].PduRDestTxBufferRef;
		PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].SduLength = Length;
		#if(STD_ON == PDUR_META_DATA_SUPPORT)
		PduR_Memcpy(PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].MetaData,info->SduDataPtr,metaDataLength);
		#endif
		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = FALSE;
		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = 0;
		*bufferSizePtr = PduR_TxBuffer[pduRDestTxBuffeId].PduRPduMaxLength;
		bufQeqReturn = BUFREQ_OK;
	}
	return bufQeqReturn;
}
/*1:n Rx Tp Pdu GateWay(more than one Tp Module,zero or one Up Module),when start of reception*/
FUNC(BufReq_ReturnType, PDUR_CODE)
PduR_StartOfReceptionToMoreModuleHandle
(
	PduIdType SrcPduId,
	uint8 DestPduSum,
	P2CONST(PduInfoType, AUTOMATIC, PDUR_APPL_DATA) info,
	PduLengthType Length,
	P2VAR(PduLengthType, AUTOMATIC, PDUR_APPL_DATA) bufferSizePtr
)
{
	BufReq_ReturnType bufQeqReturn = BUFREQ_E_NOT_OK;
	PduIdType gatewayTpRunTimeId;
	PduIdType pduRDestPduId;
	boolean needCheckTxConfirm = FALSE;
	uint8 findTpBuffer = 0xff;
	uint16 pduRDestTxBuffeId;
	uint16 cnt = 0;
	/*MF tp pdu gateway,need store in tp buffer*/
	if(FALSE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].TpPduIsSF)
	{
		/*find one valid tp buffer.if not find,return 0xff*/
		findTpBuffer = PduR_FindValidTpBuffer(SrcPduId,Length);
		/*find the valid tp buffer*/
		if(0xff != findTpBuffer)
		{
			/*set the tp buffer runtime state*/
			PduR_TpBuffer[findTpBuffer].used = TRUE;
			PduR_TpBuffer[findTpBuffer].RxBufferOffset = 0;
			PduR_TpBuffer[findTpBuffer].SduLength = Length;
			PduR_TpBuffer[findTpBuffer].PduHandleId = SrcPduId;
            #if(STD_ON == PDUR_META_DATA_SUPPORT)
			PduR_Memcpy(PduR_TpBuffer[findTpBuffer].MetaData,info->SduDataPtr,PduR_ConfigStd->PduRSrcPduRef[SrcPduId].MetaDataLength);
            #endif
			/*gateway-on-the-fly*/
			if(TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].GatewayOnTheFly)
			{
				for(cnt = 0;cnt < DestPduSum;cnt++)
				{
					pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].PduRDestPduIdRef[cnt];
					if(TRUE == PduRIsEnabled[pduRDestPduId])
					{
						gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly = TRUE;
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId = findTpBuffer;
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].CopyCompleteTpBufferNumber = 0;
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = FALSE;
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = 0;
						if(0 == PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].PduRTpThreshold)
						{
							/*gateway MF pdu to Tp mode by LoTp_Transmit*/
							if(E_NOT_OK == PduR_GateWayMFToTp(SrcPduId,pduRDestPduId))
							{
								needCheckTxConfirm = TRUE;
								PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId = 0xff;
								PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
							}
							PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly = FALSE;
						}
					}
				}
				if(TRUE == needCheckTxConfirm)
				{
					if(TRUE == PduR_AtLeastOneDestIsNotTxConfirm(SrcPduId))
					{
						bufQeqReturn = BUFREQ_OK;
						*bufferSizePtr = PduR_TpBuffer[findTpBuffer].TpBufferLength;
					}
					else
					{
						bufQeqReturn = BUFREQ_E_NOT_OK;
						/*clear the tp buffer runtime state*/
						PduR_ClearBufferAndStateOfGateWayTpPdu(SrcPduId);
					}
				}
				else
				{
					bufQeqReturn = BUFREQ_OK;
					*bufferSizePtr = PduR_TpBuffer[findTpBuffer].TpBufferLength;
				}
			}
			/*not gateway-on-the-fly*/
			else
			{
				for(cnt = 0;cnt < DestPduSum;cnt++)
				{
					pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].PduRDestPduIdRef[cnt];
					if(TRUE == PduRIsEnabled[pduRDestPduId])
					{
						gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId = findTpBuffer;
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = FALSE;
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = 0;
					}
				}
				*bufferSizePtr = PduR_TpBuffer[findTpBuffer].TpBufferLength;
				bufQeqReturn = BUFREQ_OK;
			}
		}
		else
		{
			bufQeqReturn = BUFREQ_E_OVFL;
		}
	}
	/*SF tp pdu gateway,need store in dedicated buffer*/
	else
	{
    	for(cnt = 0;cnt < DestPduSum;cnt++)
    	{
    		pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].PduRDestPduIdRef[cnt];
    		if(TRUE == PduRIsEnabled[pduRDestPduId])
    		{
    			pduRDestTxBuffeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].PduRDestTxBufferRef;
				PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].SduLength = Length;
                #if(STD_ON == PDUR_META_DATA_SUPPORT)
				PduR_Memcpy(PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].MetaData,info->SduDataPtr,PduR_ConfigStd->PduRSrcPduRef[SrcPduId].MetaDataLength);
                #endif
				gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
				PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = FALSE;
				PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = 0;
    		}
    	}
    	/*configuration guarantee the buffer length >= SF Pdu Length*/
		*bufferSizePtr = Length;
		bufQeqReturn = BUFREQ_OK;
	}
	return bufQeqReturn;
}
/*at least one dest pdu state is enabled*/
FUNC(boolean, PDUR_CODE)
PduR_AtLeastOneDestIsEnabled(uint16 PduRSrcPduId)
{
	boolean retValue = FALSE;
	uint8 pduDestSum;
	uint16 pduRDestPduId;
	uint16 cnt;
	pduDestSum = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].PduDestSum;
	for(cnt = 0;(cnt < pduDestSum)&&(FALSE == retValue);cnt++)
	{
		pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].PduRDestPduIdRef[cnt];
		if(TRUE == PduRIsEnabled[pduRDestPduId])
		{
			retValue = TRUE;
		}
	}
	return retValue;
}
/*Rx Tp Pdu gateway to only one Tp Module Pdu handle,when copy Rx Data*/
FUNC(BufReq_ReturnType, PDUR_CODE)
PduR_CopyRxDataToOneTpHandle(PduIdType SrcPduId,PduIdType DestPduId,P2CONST(PduInfoType, AUTOMATIC, PDUR_APPL_DATA) info,P2VAR(PduLengthType, AUTOMATIC, PDUR_APPL_DATA)BufferSizePtr)
{
	BufReq_ReturnType bufQeqReturn = BUFREQ_E_NOT_OK;
	uint16 pduRDestTxBuffeId;
	uint8 tpBufferId;
	uint16 gatewayTpRunTimeId;
	uint16 pduRTpThreshold;
	/*the tp data is stored in Dedicated buffer(SF)*/
	if(TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].TpPduIsSF)
	{
		pduRDestTxBuffeId = PduR_ConfigStd->PduRDestPduRef[DestPduId].PduRDestTxBufferRef;
		if(info->SduLength == PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].SduLength)
		{
			PduR_Memcpy(PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].TxBufferData,info->SduDataPtr,info->SduLength);
			*BufferSizePtr = 0;
			bufQeqReturn = BUFREQ_OK;
		}
		else
		{
			bufQeqReturn = BUFREQ_E_NOT_OK;
		}
	}
	/*the tp data is stored in Tp buffer(FF and CF)*/
	else
	{
		/*find the valid tp buffer to copy the data*/
		tpBufferId = PduR_FindTpBuffer(SrcPduId);
		if(0xff != tpBufferId)
		{
			/*copy the rx pdu data to the tp buffer*/
			bufQeqReturn = PduR_CopyRxTpDataToTpBuffer(tpBufferId,info,BufferSizePtr);
			if((BUFREQ_OK == bufQeqReturn)
					&& (TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].GatewayOnTheFly))
			{
				pduRTpThreshold = PduR_ConfigStd->PduRDestPduRef[DestPduId].PduRTpThreshold;
				gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[DestPduId].GateWayTpRunTimeIndex;
				if((TRUE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly)
						&& (PduR_TpBuffer[tpBufferId].RxBufferOffset >= pduRTpThreshold))
				{
					/*gateway MF pdu to Tp mode by LoTp_Transmit*/
					if(E_NOT_OK == PduR_GateWayMFToTp(SrcPduId,DestPduId))
					{
						bufQeqReturn = BUFREQ_E_NOT_OK;
					}
					PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly = FALSE;
				}
			}
		}
		/*no valid tp buffer*/
		else
		{
			bufQeqReturn = BUFREQ_E_NOT_OK;
		}
	}
	return bufQeqReturn;
}
/*1:n Rx Tp Pdu GateWay(more than one Tp Module,zero or one Up Module),when copy Rx Data*/
FUNC(BufReq_ReturnType, PDUR_CODE)
PduR_CopyRxDataToMoreModuleHandle(PduIdType SrcPduId,uint8 DestPduSum,P2CONST(PduInfoType, AUTOMATIC, PDUR_APPL_DATA) info,P2VAR(PduLengthType, AUTOMATIC, PDUR_APPL_DATA)BufferSizePtr)
{
	BufReq_ReturnType bufQeqReturn = BUFREQ_E_NOT_OK;
	PduIdType pduRDestPduId;
	uint16 gatewayTpRunTimeId;
	uint16 pduRTpThreshold;
	uint16 pduRDestTxBuffeId;
	uint8 tpBufferId;
	uint16 cnt;
	/*the tp data is stored in Dedicated buffer(SF)*/
	if(TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].TpPduIsSF)
	{
		for(cnt = 0;cnt < DestPduSum;cnt++)
		{
			pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].PduRDestPduIdRef[cnt];
			gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
			if(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
			{
				if(TRUE == PduRIsEnabled[pduRDestPduId])
				{
					pduRDestTxBuffeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].PduRDestTxBufferRef;
					if(info->SduLength == PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].SduLength)
					{
						PduR_Memcpy(PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].TxBufferData,info->SduDataPtr,info->SduLength);
						*BufferSizePtr = 0;
						bufQeqReturn = BUFREQ_OK;
					}
					else
					{
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
					}
				}
				else
				{
					PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
				}
			}
		}
		if(FALSE == PduR_AtLeastOneDestIsNotTxConfirm(SrcPduId))
		{
			bufQeqReturn = BUFREQ_E_NOT_OK;
		}
	}
	/*the tp data is stored in Tp buffer(FF and CF)*/
	else
	{
		for(cnt = 0;cnt < DestPduSum;cnt++)
		{
			pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].PduRDestPduIdRef[cnt];
			if(FALSE == PduRIsEnabled[pduRDestPduId])
			{
				gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
				PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
			}
		}
		/*at least one dest pdu need use the rx pdu data*/
		if(TRUE == PduR_AtLeastOneDestIsNotTxConfirm(SrcPduId))
		{
			/*find the valid tp buffer to copy the data*/
			tpBufferId = PduR_FindTpBuffer(SrcPduId);
			if(0xff != tpBufferId)
			{
				/*copy the rx pdu data to the tp buffer*/
				bufQeqReturn = PduR_CopyRxTpDataToTpBuffer(tpBufferId,info,BufferSizePtr);
				if((BUFREQ_OK == bufQeqReturn)
						&& (TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].GatewayOnTheFly))
				{
					for(cnt = 0;cnt < DestPduSum;cnt++)
					{
						pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].PduRDestPduIdRef[cnt];
						gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
						if(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
						{
							pduRTpThreshold = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].PduRTpThreshold;
							if((TRUE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly)
									&& (PduR_TpBuffer[tpBufferId].RxBufferOffset >= pduRTpThreshold))
							{
								/*gateway MF pdu to Tp mode by LoTp_Transmit*/
								if(E_NOT_OK == PduR_GateWayMFToTp(SrcPduId,pduRDestPduId))
								{
									PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
								}
								PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly = FALSE;
							}
						}
					}
					if(FALSE == PduR_AtLeastOneDestIsNotTxConfirm(SrcPduId))
					{
						bufQeqReturn = BUFREQ_E_NOT_OK;
					}
				}
			}
			/*no valid tp buffer*/
			else
			{
				bufQeqReturn = BUFREQ_E_NOT_OK;
			}
		}
		else
		{
			bufQeqReturn = BUFREQ_E_NOT_OK;
		}
	}
	return bufQeqReturn;
}
/*Rx Tp Pdu gateway to only one Tp Module Pdu handle,when Rx Indication*/
FUNC(void, PDUR_CODE)
PduR_RxIndicationToOneTpHandle(PduIdType SrcPduId,PduIdType DestPduId)
{
	uint16 gatewayTpRunTimeId;
	/*pdu data stored in tp buffer*/
	if(FALSE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].TpPduIsSF)
	{
		/*gateway-on-the-fly mode,but the PduRTpThreshold is large than the pdu length*/
		if(TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].GatewayOnTheFly)
		{
			gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[DestPduId].GateWayTpRunTimeIndex;
			if(TRUE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly)
			{
				/*gateway MF pdu to Tp mode by LoTp_Transmit*/
				if(E_OK == PduR_GateWayMFToTp(SrcPduId,DestPduId))
				{
					PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly = FALSE;
				}
				else
				{
					PduR_ClearBufferAndStateOfGateWayTpPdu(SrcPduId);
				}
			}
		}
		/*Receive all pdu data,then gateway to other tp module*/
		else
		{
			/*gateway MF pdu to Tp mode by LoTp_Transmit*/
			if(E_NOT_OK == PduR_GateWayMFToTp(SrcPduId,DestPduId))
			{
				PduR_ClearBufferAndStateOfGateWayTpPdu(SrcPduId);
			}
		}
	}
	/*pdu data stored in dedicated buffer(SF)*/
	else
	{
		/*gateway SF pdu to Tp mode by LoTp_Transmit*/
		if(E_NOT_OK == PduR_GateWaySFToTp(SrcPduId,DestPduId))
		{
			PduR_ClearBufferAndStateOfGateWayTpPdu(SrcPduId);
		}
	}
	return;
}
/*1:n Rx Tp Pdu GateWay(more than one Tp Module,zero or one Up Module),when Rx Indication*/
FUNC(void, PDUR_CODE)
PduR_RxIndicationToMoreModuleHandle(PduIdType SrcPduId,uint8 DestPduSum)
{
	PduIdType pduRDestPduId;
	uint16 gatewayTpRunTimeId;
	boolean checkAllDestTxConfirmState = FALSE;
	uint8 cnt;
	uint8 destModuleIndex;
	uint8 destModule;
	for(cnt = 0;cnt < DestPduSum;cnt++)
	{
		pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].PduRDestPduIdRef[cnt];
		if(FALSE == PduRIsEnabled[pduRDestPduId])
		{
			gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
			PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
		}
	}
	if(TRUE == PduR_AtLeastOneDestIsNotTxConfirm(SrcPduId))
	{
		for(cnt = 0;cnt < DestPduSum;cnt++)
		{
			pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].PduRDestPduIdRef[cnt];
			gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
			if(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
			{
				destModuleIndex = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].BswModuleIndex;
				destModule = PduR_BswModuleConfigData[destModuleIndex].PduRBswModuleRef;
				switch(destModule)
				{
						#if(STD_ON == PDUR_COM_SUPPORT)
						case PDUR_COM:
						#endif
						#if(STD_ON == PDUR_LDCOM_SUPPORT)
						case PDUR_LDCOM:
						#endif
						#if(STD_ON == PDUR_SECOC_SUPPORT)
						case PDUR_SECOC:
						#endif
						#if(STD_ON == PDUR_DCM_SUPPORT)
						case PDUR_DCM:
						#endif
						#if(STD_ON == PDUR_J1939DCM_SUPPORT)
						case PDUR_J1939DCM:
						#endif
						if(FALSE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].TpPduIsSF)
						{
							/*MF Tp pdu 1:n(n>1) route:route the pdu to one up mode*/
							PduR_RouteMFtoUp(destModule,SrcPduId,pduRDestPduId);
						}
						else
						{
							/*SF Tp pdu 1:n(n>1) route:route the pdu to one up mode*/
							PduR_RouteSFtoUp(destModule,SrcPduId,pduRDestPduId);
						}
						checkAllDestTxConfirmState = TRUE;
						break;
					default:/*Tp layer:Gateway pdu*/
						if(FALSE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].TpPduIsSF)
						{
							/*gateway-on-the-fly mode,but the PduRTpThreshold is large than the pdu length*/
							if(TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].GatewayOnTheFly)
							{
								if(TRUE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly)
								{
									/*gateway MF pdu to Tp mode by LoTp_Transmit*/
									if(E_NOT_OK == PduR_GateWayMFToTp(SrcPduId,pduRDestPduId))
									{
										PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
										checkAllDestTxConfirmState = TRUE;
									}
									PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly = FALSE;
								}
							}
							/*Receive all pdu data,then gateway to other tp module*/
							else
							{
								/*gateway MF pdu to Tp mode by LoTp_Transmit*/
								if(E_NOT_OK == PduR_GateWayMFToTp(SrcPduId,pduRDestPduId))
								{
									PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
									checkAllDestTxConfirmState = TRUE;
								}
							}
						}
						else
						{
							/*gateway SF pdu to Tp mode by LoTp_Transmit*/
							if(E_NOT_OK == PduR_GateWaySFToTp(SrcPduId,pduRDestPduId))
							{
								PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
								checkAllDestTxConfirmState = TRUE;
							}
						}
						break;
				}
			}
		}
		if(TRUE == checkAllDestTxConfirmState)
		{
			if(FALSE == PduR_AtLeastOneDestIsNotTxConfirm(SrcPduId))
			{
				PduR_ClearBufferAndStateOfGateWayTpPdu(SrcPduId);
			}
		}
	}
	else
	{
		PduR_ClearBufferAndStateOfGateWayTpPdu(SrcPduId);
	}
	return;
}
/*one Tp Pdu route to one Tp Pdu,the dest pdu copy tx data handle*/
FUNC(BufReq_ReturnType, PDUR_CODE)
PduR_OneDestCopyTxDataFromTpHandle
(
	PduIdType SrcPduId,
	PduIdType DestPduId,
	P2CONST(PduInfoType, AUTOMATIC, PDUR_APPL_DATA) info,
	P2VAR(RetryInfoType, AUTOMATIC, PDUR_APPL_DATA) retry,
	P2VAR(PduLengthType, AUTOMATIC, PDUR_APPL_DATA) availableDataPtr
)
{
	BufReq_ReturnType bufQeqReturn = BUFREQ_E_NOT_OK;
	uint16 gatewayTpRunTimeId;
	uint8 tpBufferId;
	uint8 nextTpBufferId;
	uint16 nextTpBufferNeedCopyLength;
	uint16 pduRDestTxBuffeId;
	gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[DestPduId].GateWayTpRunTimeIndex;
	if(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
	{
		/*Gateway Multi-Frame I-PDU*/
		if(FALSE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].TpPduIsSF)
		{
			tpBufferId = PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId;
			/*gateway-on-the-fly mode*/
			if(TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].GatewayOnTheFly)
			{
				if((NULL_PTR == retry) || (TP_DATACONF == retry->TpDataState))
				{
					nextTpBufferId = PduR_TpBuffer[tpBufferId].NextTpBufferId;
					/*the active tp buffer have stored full and other tp buffer have start store Rx Tp Pdu data*/
					if(0xff != nextTpBufferId)
					{
						/*don't copy data,just update the available data length and tell Lo Tp Module */
						if(0 == info->SduLength)
						{
							*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset + PduR_TpBuffer[nextTpBufferId].RxBufferOffset
									- PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
							bufQeqReturn = BUFREQ_OK;
						}
						/*copy data and tell Lo Tp Module the available data length*/
						else
						{
							/*the active buffer have not copy completely*/
							if((PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset + info->SduLength) <= PduR_TpBuffer[tpBufferId].RxBufferOffset)
							{
								PduR_Memcpy
								(
									info->SduDataPtr,
									&PduR_TpBuffer[tpBufferId].TpBufferData[PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset],
									info->SduLength
								);
								PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset += info->SduLength;
								*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset + PduR_TpBuffer[nextTpBufferId].RxBufferOffset
										- PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
								bufQeqReturn = BUFREQ_OK;
							}
							/*the active buffer have copy completely,and next tp buffer also copy some data*/
							else
							{
								nextTpBufferNeedCopyLength = PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset + info->SduLength
										- PduR_TpBuffer[tpBufferId].RxBufferOffset;
								/*don't have enough rx valid data for copy*/
								if(nextTpBufferNeedCopyLength > PduR_TpBuffer[nextTpBufferId].RxBufferOffset)
								{
									bufQeqReturn = BUFREQ_E_BUSY;
								}
								/*have enough rx valid data for copy*/
								else
								{
									PduR_Memcpy
									(
										info->SduDataPtr,
										&PduR_TpBuffer[tpBufferId].TpBufferData[PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset],
										(info->SduLength - nextTpBufferNeedCopyLength)
									);
									PduR_Memcpy
									(
										&info->SduDataPtr[info->SduLength - nextTpBufferNeedCopyLength],
										&PduR_TpBuffer[nextTpBufferId].TpBufferData[0],
										nextTpBufferNeedCopyLength
									);
									PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = nextTpBufferNeedCopyLength;
									PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId = nextTpBufferId;
									*availableDataPtr = PduR_TpBuffer[nextTpBufferId].RxBufferOffset - nextTpBufferNeedCopyLength;
									bufQeqReturn = BUFREQ_OK;
									/*clear the tp buffer which have been copyed all data*/
									PduR_TpBuffer[tpBufferId].NextTpBufferId = 0xff;
									PduR_TpBuffer[tpBufferId].PduHandleId = 0xffff;
									PduR_TpBuffer[tpBufferId].RxBufferOffset = 0;
									PduR_TpBuffer[tpBufferId].SduLength = 0;
									PduR_TpBuffer[tpBufferId].used = FALSE;
								}
							}
						}
					}
					/*the active tp buffer have stored not full*/
					else
					{
						/*don't copy data,just update the available data length and tell Lo Tp Module */
						if(0 == info->SduLength)
						{
							*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset
									- PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
							bufQeqReturn = BUFREQ_OK;
						}
						/*copy data and tell Lo Tp Module the available data length*/
						else
						{
							if((PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset + info->SduLength) <= PduR_TpBuffer[tpBufferId].RxBufferOffset)
							{
								PduR_Memcpy
								(
									info->SduDataPtr,
									&PduR_TpBuffer[tpBufferId].TpBufferData[PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset],
									info->SduLength
								);
								PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset += info->SduLength;
								*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset
										- PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
								bufQeqReturn = BUFREQ_OK;
							}
							else
							{
								bufQeqReturn = BUFREQ_E_BUSY;
							}
						}
					}
				}
				else
				{
					bufQeqReturn = BUFREQ_E_NOT_OK;
				}
			}
			/*not gateway-on-the-fly mode*/
			else
			{
				if((NULL_PTR != retry) && (TP_DATARETRY == retry->TpDataState))
				{
					if(PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset >= retry->TxTpDataCnt)
					{
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset -= retry->TxTpDataCnt;
					}
					/*will not happen general,TP module guarantee*/
					else
					{
						/*re-copy data from 0*/
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = 0;
					}
				}
				/*don't copy data,just update the available data length and tell Lo Tp Module */
				if(0 == info->SduLength)
				{
					*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset - PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
					bufQeqReturn = BUFREQ_OK;
				}
				/*copy data and tell Lo Tp Module the available data length*/
				else
				{
					if((PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset + info->SduLength) <= PduR_TpBuffer[tpBufferId].RxBufferOffset)
					{
						PduR_Memcpy
						(
							info->SduDataPtr,
							&PduR_TpBuffer[tpBufferId].TpBufferData[PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset],
							info->SduLength
						);
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset += info->SduLength;
						*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset - PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
						bufQeqReturn = BUFREQ_OK;
					}
					/*will not happen general,TP module guarantee*/
					else
					{
						bufQeqReturn = BUFREQ_E_NOT_OK;
					}
				}
			}
		}
		/*Gateway Single-Frame I-PDU*/
		else
		{
			pduRDestTxBuffeId = PduR_ConfigStd->PduRDestPduRef[DestPduId].PduRDestTxBufferRef;
			if(info->SduLength == PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].SduLength)
			{
				PduR_Memcpy
				(
					info->SduDataPtr,
					PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].TxBufferData,
					info->SduLength
				);
				*availableDataPtr = 0;
				bufQeqReturn = BUFREQ_OK;
			}
			else
			{
				bufQeqReturn = BUFREQ_E_NOT_OK;
			}
		}
	}
	else
	{
		bufQeqReturn = BUFREQ_E_NOT_OK;
	}

	return bufQeqReturn;
}
/*one Tp Pdu route to more module Pdus,one dest Tp Pdu copy tx data handle*/
FUNC(BufReq_ReturnType, PDUR_CODE)
PduR_MoreDestCopyTxDataFromTpHandle
(
	PduIdType SrcPduId,
	PduIdType DestPduId,
	P2CONST(PduInfoType, AUTOMATIC, PDUR_APPL_DATA) info,
	P2VAR(RetryInfoType, AUTOMATIC, PDUR_APPL_DATA) retry,
	P2VAR(PduLengthType, AUTOMATIC, PDUR_APPL_DATA) availableDataPtr
)
{
	BufReq_ReturnType bufQeqReturn = BUFREQ_E_NOT_OK;
	uint16 gatewayTpRunTimeId;
	uint8 tpBufferId;
	uint8 nextTpBufferId;
	uint16 nextTpBufferNeedCopyLength;
	uint16 pduRDestTxBuffeId;
	gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[DestPduId].GateWayTpRunTimeIndex;
	if((TRUE == PduRIsEnabled[DestPduId]) && (FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation))
	{
		/*Gateway Multi-Frame I-PDU*/
		if(FALSE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].TpPduIsSF)
		{
			tpBufferId = PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId;
			/*gateway-on-the-fly mode*/
			if(TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPduId].GatewayOnTheFly)
			{
				nextTpBufferId = PduR_TpBuffer[tpBufferId].NextTpBufferId;
				/*the active tp buffer have stored full and other tp buffer have start store Rx Tp Pdu data*/
				if(0xff != nextTpBufferId)
				{
					/*don't copy data,just update the available data length and tell Lo Tp Module */
					if(0 == info->SduLength)
					{
						*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset + PduR_TpBuffer[nextTpBufferId].RxBufferOffset
								- PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
						bufQeqReturn = BUFREQ_OK;
					}
					/*copy data and tell Lo Tp Module the available data length*/
					else
					{
						/*the active buffer have not copy completely*/
						if((PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset + info->SduLength) <= PduR_TpBuffer[tpBufferId].RxBufferOffset)
						{
							PduR_Memcpy
							(
								info->SduDataPtr,
								&PduR_TpBuffer[tpBufferId].TpBufferData[PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset],
								info->SduLength
							);
							PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset += info->SduLength;
							*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset + PduR_TpBuffer[nextTpBufferId].RxBufferOffset
									- PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
							bufQeqReturn = BUFREQ_OK;
						}
						/*the active buffer have copy completely,and next tp buffer also copy some data*/
						else
						{
							nextTpBufferNeedCopyLength = PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset + info->SduLength
									- PduR_TpBuffer[tpBufferId].RxBufferOffset;
							/*don't have enough rx valid data for copy*/
							if(nextTpBufferNeedCopyLength > PduR_TpBuffer[nextTpBufferId].RxBufferOffset)
							{
								bufQeqReturn = BUFREQ_E_BUSY;
							}
							/*have enough rx valid data for copy*/
							else
							{
								PduR_Memcpy
								(
									&info->SduDataPtr[0],
									&PduR_TpBuffer[tpBufferId].TpBufferData[PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset],
									(info->SduLength - nextTpBufferNeedCopyLength)
								);
								PduR_Memcpy
								(
									&info->SduDataPtr[info->SduLength - nextTpBufferNeedCopyLength],
									&PduR_TpBuffer[nextTpBufferId].TpBufferData[0],
									nextTpBufferNeedCopyLength
								);
								PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = nextTpBufferNeedCopyLength;
								PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId = nextTpBufferId;
								PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].CopyCompleteTpBufferNumber++;
								*availableDataPtr = PduR_TpBuffer[nextTpBufferId].RxBufferOffset - nextTpBufferNeedCopyLength;
								bufQeqReturn = BUFREQ_OK;
								/*if the tp buffer which have been copyed all data by all dest Tp Pdus,need clear the tp buffer*/
								if(TRUE == PduR_GateWayOnTheFlyNeedClearTpBuffer(SrcPduId,PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].CopyCompleteTpBufferNumber))
								{
									PduR_TpBuffer[tpBufferId].NextTpBufferId = 0xff;
									PduR_TpBuffer[tpBufferId].PduHandleId = 0xffff;
									PduR_TpBuffer[tpBufferId].RxBufferOffset = 0;
									PduR_TpBuffer[tpBufferId].SduLength = 0;
									PduR_TpBuffer[tpBufferId].used = FALSE;
								}
							}
						}
					}
				}
				/*the active tp buffer have stored not full*/
				else
				{
					/*don't copy data,just update the available data length and tell Lo Tp Module */
					if(0 == info->SduLength)
					{
						*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset
								- PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
						bufQeqReturn = BUFREQ_OK;
					}
					/*copy data and tell Lo Tp Module the available data length*/
					else
					{
						/*have enough rx valid data for copy*/
						if((PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset + info->SduLength) <= PduR_TpBuffer[tpBufferId].RxBufferOffset)
						{
							PduR_Memcpy
							(
								info->SduDataPtr,
								&PduR_TpBuffer[tpBufferId].TpBufferData[PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset],
								info->SduLength
							);
							PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset += info->SduLength;
							*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset
									- PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
							bufQeqReturn = BUFREQ_OK;
						}
						/*don't have enough rx valid data for copy*/
						else
						{
							bufQeqReturn = BUFREQ_E_BUSY;
						}
					}
				}
			}
			/*not gateway-on-the-fly mode*/
			else
			{
				if((NULL_PTR != retry) && (TP_DATARETRY == retry->TpDataState))
				{
					if(PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset >= retry->TxTpDataCnt)
					{
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset -= retry->TxTpDataCnt;
					}
					/*will not happen general,TP module guarantee*/
					else
					{
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = 0;
					}
				}
				/*don't copy data,just update the available data length and tell Lo Tp Module */
				if(0 == info->SduLength)
				{
					*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset - PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
					bufQeqReturn = BUFREQ_OK;
				}
				/*copy data and tell Lo Tp Module the available data length*/
				else
				{
					if((PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset + info->SduLength) <= PduR_TpBuffer[tpBufferId].RxBufferOffset)
					{
						PduR_Memcpy
						(
							info->SduDataPtr,
							&PduR_TpBuffer[tpBufferId].TpBufferData[PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset],
							info->SduLength
						);
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset += info->SduLength;
						*availableDataPtr = PduR_TpBuffer[tpBufferId].RxBufferOffset - PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset;
						bufQeqReturn = BUFREQ_OK;
					}
					/*will not happen general,TP module guarantee*/
					else
					{
						bufQeqReturn = BUFREQ_E_NOT_OK;
					}
				}
			}
		}
		/*Gateway Single-Frame I-PDU*/
		else
		{
			pduRDestTxBuffeId = PduR_ConfigStd->PduRDestPduRef[DestPduId].PduRDestTxBufferRef;
			if(info->SduLength == PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].SduLength)
			{
				PduR_Memcpy
				(
					info->SduDataPtr,
					PduR_TxBuffer[pduRDestTxBuffeId].PduRTxBufferRef[0].TxBufferData,
					info->SduLength
				);
				*availableDataPtr = 0;
				bufQeqReturn = BUFREQ_OK;
			}
			else
			{
				bufQeqReturn = BUFREQ_E_NOT_OK;
			}
		}
	}
	else
	{
		bufQeqReturn = BUFREQ_E_NOT_OK;
	}

	return bufQeqReturn;
}
/*one up module Tx tp pdu(SF) to more Tp Module Pdus,the Lo Tp copy tx data*/
FUNC(BufReq_ReturnType, PDUR_CODE)
PduR_UpMulticastTpCopyData
(
	uint8 SoureModule,
	PduIdType SrcPduId,
	PduIdType DestPduId,
	P2CONST(PduInfoType, AUTOMATIC, PDUR_APPL_DATA) info,
	P2VAR(PduLengthType, AUTOMATIC, PDUR_APPL_DATA) availableDataPtr
)
{
	BufReq_ReturnType bufQeqReturn = BUFREQ_E_NOT_OK;
	P2VAR(RetryInfoType, AUTOMATIC, COM_APPL_DATA) pduRRetry = NULL_PTR;
	PduIdType upPduId;
	upPduId = PduR_ConfigStd->PduRSrcPduRef[SrcPduId].PduRDestModulePduIndex;
	if(TRUE == PduRIsEnabled[DestPduId])
	{
		switch(SoureModule)
		{
			#if(STD_ON == PDUR_COM_SUPPORT)
			case PDUR_COM:
				/*first dest copy data*/
				if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer)
				{
					pduRRetry->TpDataState = TP_CONFPENDING;
					bufQeqReturn = Com_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				/*not first dest copy data,not last dest copy data*/
				else
				{
					pduRRetry->TpDataState = TP_DATARETRY;
					pduRRetry->TxTpDataCnt = info->SduLength;
					bufQeqReturn = Com_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				break;
			#endif
			#if(STD_ON == PDUR_LDCOM_SUPPORT)
			case PDUR_LDCOM:
				/*first dest copy data*/
				if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer)
				{
					pduRRetry->TpDataState = TP_CONFPENDING;
					bufQeqReturn = LdCom_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				/*not first dest copy data,not last dest copy data*/
				else
				{
					pduRRetry->TpDataState = TP_DATARETRY;
					pduRRetry->TxTpDataCnt = info->SduLength;
					bufQeqReturn = LdCom_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				break;
			#endif
			#if(STD_ON == PDUR_SECOC_SUPPORT)
			case PDUR_SECOC:
				/*first dest copy data*/
				if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer)
				{
					pduRRetry->TpDataState = TP_CONFPENDING;
					bufQeqReturn = SecOC_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				/*not first dest copy data,not last dest copy data*/
				else
				{
					pduRRetry->TpDataState = TP_DATARETRY;
					pduRRetry->TxTpDataCnt = info->SduLength;
					bufQeqReturn = SecOC_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				break;
			#endif
			#if(STD_ON == PDUR_DCM_SUPPORT)
			case PDUR_DCM:
				/*first dest copy data*/
				if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer)
				{
					pduRRetry->TpDataState = TP_CONFPENDING;
					bufQeqReturn = Dcm_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				/*not first dest copy data,not last dest copy data*/
				else
				{
					pduRRetry->TpDataState = TP_DATARETRY;
					pduRRetry->TxTpDataCnt = info->SduLength;
					bufQeqReturn = Dcm_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				break;
			#endif
			#if(STD_ON == PDUR_J1939DCM_SUPPORT)
			case PDUR_J1939DCM:
				/*first dest copy data*/
				if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer)
				{
					pduRRetry->TpDataState = TP_CONFPENDING;
					bufQeqReturn = J1939Dcm_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				/*not first dest copy data,not last dest copy data*/
				else
				{
					pduRRetry->TpDataState = TP_DATARETRY;
					pduRRetry->TxTpDataCnt = info->SduLength;
					bufQeqReturn = J1939Dcm_CopyTxData(upPduId,info,pduRRetry,availableDataPtr);
					if(BUFREQ_OK == bufQeqReturn)
					{
						PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].DestCopyDataTimer += 1;
					}
				}
				break;
			#endif
			default:
				bufQeqReturn = BUFREQ_E_NOT_OK;
				break;
		}
	}
	else
	{
		bufQeqReturn = BUFREQ_E_NOT_OK;
	}
	return bufQeqReturn;
}
/*one up module Tx Tp Pdu to one or more dest Tp Pdu,one Tp Pdu call the TpTxConfirmation Handle*/
FUNC(void, PDUR_CODE)
PduR_UpTpTxConfirmationHandle(uint8 SoureModule,PduIdType SrcPduId,uint8 DestPduSum,PduIdType DestPduId,Std_ReturnType Result)
{
	PduIdType upPduId;
	upPduId = PduR_ConfigStd->PduRSrcPduRef[SrcPduId].PduRDestModulePduIndex;
	switch(SoureModule)
	{
		#if(STD_ON == PDUR_COM_SUPPORT)
		case PDUR_COM:
			if(DestPduSum > 1)
			{
				if((E_OK == Result) && (TRUE == PduRIsEnabled[DestPduId]))
				{
					PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex] = TRUE;
				}
				if(0 < PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
				{
					PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber--;
					if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
					{
						if(TRUE == PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex])
						{
							Com_TpTxConfirmation(upPduId,E_OK);
						}
						else
						{
							Com_TpTxConfirmation(upPduId,E_NOT_OK);
						}
					}
				}
			}
			else
			{
				if(TRUE == PduRIsEnabled[DestPduId])
				{
					Com_TpTxConfirmation(upPduId,Result);
				}
				else
				{
					Com_TpTxConfirmation(upPduId,E_NOT_OK);
				}
			}
			break;
		#endif
		#if(STD_ON == PDUR_LDCOM_SUPPORT)
		case PDUR_LDCOM:
			if(DestPduSum > 1)
			{
				if((E_OK == Result) && (TRUE == PduRIsEnabled[DestPduId]))
				{
					PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex] = TRUE;
				}
				if(0 < PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
				{
					PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber--;
					if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
					{
						if(TRUE == PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex])
						{
							LdCom_TpTxConfirmation(upPduId,E_OK);
						}
						else
						{
							LdCom_TpTxConfirmation(upPduId,E_NOT_OK);
						}
					}
				}
			}
			else
			{
				if(TRUE == PduRIsEnabled[DestPduId])
				{
					LdCom_TpTxConfirmation(upPduId,Result);
				}
				else
				{
					LdCom_TpTxConfirmation(upPduId,E_NOT_OK);
				}
			}
			break;
		#endif
		#if(STD_ON == PDUR_SECOC_SUPPORT)
		case PDUR_SECOC:
			if(DestPduSum > 1)
			{
				if((E_OK == Result) && (TRUE == PduRIsEnabled[DestPduId]))
				{
					PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex] = TRUE;
				}
				if(0 < PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
				{
					PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber--;
					if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
					{
						if(TRUE == PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex])
						{
							SecOC_TpTxConfirmation(upPduId,E_OK);
						}
						else
						{
							SecOC_TpTxConfirmation(upPduId,E_NOT_OK);
						}
					}
				}
			}
			else
			{
				if(TRUE == PduRIsEnabled[DestPduId])
				{
					SecOC_TpTxConfirmation(upPduId,Result);
				}
				else
				{
					SecOC_TpTxConfirmation(upPduId,E_NOT_OK);
				}
			}
			break;
		#endif
		#if(STD_ON == PDUR_DCM_SUPPORT)
		case PDUR_DCM:
			if(DestPduSum > 1)
			{
				if((E_OK == Result) && (TRUE == PduRIsEnabled[DestPduId]))
				{
					PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex] = TRUE;
				}
				if(0 < PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
				{
					PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber--;
					if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
					{
						if(TRUE == PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex])
						{
							Dcm_TpTxConfirmation(upPduId,E_OK);
						}
						else
						{
							Dcm_TpTxConfirmation(upPduId,E_NOT_OK);
						}
					}
				}
			}
			else
			{
				if(TRUE == PduRIsEnabled[DestPduId])
				{
					Dcm_TpTxConfirmation(upPduId,Result);
				}
				else
				{
					Dcm_TpTxConfirmation(upPduId,E_NOT_OK);
				}
			}
			break;
		#endif
		#if(STD_ON == PDUR_J1939DCM_SUPPORT)
		case PDUR_J1939DCM:
			if(DestPduSum > 1)
			{
				if((E_OK == Result) && (TRUE == PduRIsEnabled[DestPduId]))
				{
					PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex] = TRUE;
				}
				if(0 < PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
				{
					PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber--;
					if(0 == PduR_UpTxTpMulRoute[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].TxTpMulticastIndex].ActiveDestNumber)
					{
						if(TRUE == PduR_UpTxState[PduR_ConfigStd->PduRSrcPduRef[SrcPduId].UpTxconfirmStateIndex])
						{
							J1939Dcm_TpTxConfirmation(upPduId,E_OK);
						}
						else
						{
							J1939Dcm_TpTxConfirmation(upPduId,E_NOT_OK);
						}
					}
				}
			}
			else
			{
				if(TRUE == PduRIsEnabled[DestPduId])
				{
					J1939Dcm_TpTxConfirmation(upPduId,Result);
				}
				else
				{
					J1939Dcm_TpTxConfirmation(upPduId,E_NOT_OK);
				}
			}
			break;
		#endif
		default:
			break;
	}
}
/*clear buffer and gateway state for gateway tp pdu*/
FUNC(void, PDUR_CODE)
PduR_ClearBufferAndStateOfGateWayTpPdu(uint16 PduRSrcPduId)
{
	uint8 cnt;
	uint16 pduRDestPduId;
	uint16 pduRDestTxBuffeIndex;
	uint16 gatewayTpRunTimeId;
	uint8 pduDestSum;
	pduDestSum = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].PduDestSum;
	if(FALSE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].TpPduIsSF)
	{
#if (0u < PDUR_TP_BUFFER_SUM)
		/*clear tp buffer*/
		for(cnt = 0u;cnt < PDUR_TP_BUFFER_SUM;cnt++)
		{
			if((TRUE == PduR_TpBuffer[cnt].used) && (PduRSrcPduId == PduR_TpBuffer[cnt].PduHandleId))
			{
				PduR_TpBuffer[cnt].NextTpBufferId = 0xff;
				PduR_TpBuffer[cnt].PduHandleId = 0xffff;
				PduR_TpBuffer[cnt].RxBufferOffset = 0;
				PduR_TpBuffer[cnt].SduLength = 0;
				PduR_TpBuffer[cnt].used = FALSE;
			}
		}
#endif
	}
	/*clear dedicated buffer*/
	else
	{
		for(cnt = 0;cnt < pduDestSum;cnt++)
		{
			pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].PduRDestPduIdRef[cnt];
			pduRDestTxBuffeIndex = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].PduRDestTxBufferRef;
			PduR_TxBuffer[pduRDestTxBuffeIndex].PduRTxBufferRef[0].SduLength = 0;
			PduR_TxBuffer[pduRDestTxBuffeIndex].PduRTxBufferRef[0].used = FALSE;
		}
	}
	/*clear gateway tp dest pdu run time state*/
	for(cnt = 0;cnt < pduDestSum;cnt++)
	{
		pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].PduRDestPduIdRef[cnt];
		gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId = 0xff;
		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TxBufferOffset = 0;
		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].CopyCompleteTpBufferNumber = 0;
		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].NeedGateWayOnTheFly = FALSE;
	}
	return;
}
/*1:n(n>1)Tp route,at least one dest pdu is still need transmit,return TRUE*/
FUNC(boolean, PDUR_CODE)
PduR_AtLeastOneDestIsNotTxConfirm(uint16 PduRSrcPduId)
{
	boolean retValue = FALSE;
	uint8 pduDestSum;
	PduIdType gateWayTpRunTimeId;
	uint16 cnt;
	PduIdType pduRDestPduId;
	pduDestSum = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].PduDestSum;
	for(cnt = 0;(cnt < pduDestSum)&&(FALSE == retValue);cnt++)
	{
		pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].PduRDestPduIdRef[cnt];
		gateWayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
		if((0xffff != gateWayTpRunTimeId) && (FALSE == PduR_GateWayDestTpRTSate[gateWayTpRunTimeId].TpTxConfirmation))
		{
			retValue = TRUE;
		}
	}
	return retValue;
}
#endif/*STD_ON == PDUR_TP_SUPPORT*/
/*copy data from source to dest*/
FUNC(void, PDUR_CODE)
PduR_Memcpy
(
    P2VAR(uint8, AUTOMATIC, AUTOMATIC) dest,
    P2CONST(uint8, AUTOMATIC, AUTOMATIC) source,
    uint16 length
)
{
    while(length > 0u)
    {
		*dest = *source;
        dest++;
        source++;
        length--;
    }

    return;
}
#define PDUR_STOP_SEC_CODE
#include "PduR_MemMap.h"
/*******************************************************************************
**                      Private Function Definitions                          **
*******************************************************************************/
#define PDUR_START_SEC_CODE
#include "PduR_MemMap.h"
#if(STD_ON == PDUR_TP_SUPPORT)
/*one Rx Tp Pdu gateway to more than one dest Tp Pdu used gateway-on-the-fly mode and more Tp buffer is used for the Rx Tp Pdu,
 * judge one tp buffer is copyed completely by all dest pdus or not*/
static FUNC(boolean, PDUR_CODE)
PduR_GateWayOnTheFlyNeedClearTpBuffer(PduIdType SrcPdu,uint8 CopyTpBufferNumber)
{
	boolean needClearTpBuffer = TRUE;
	uint8 pduDestSum;
	uint8 cnt;
	uint16 gatewayTpRunTimeId;
	PduIdType pduRDestPduId;
	pduDestSum = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPdu].PduDestSum;
	for(cnt = 0;(cnt < pduDestSum)&&(TRUE == needClearTpBuffer);cnt++)
	{
		pduRDestPduId = PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[SrcPdu].PduRDestPduIdRef[cnt];
		gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[pduRDestPduId].GateWayTpRunTimeIndex;
		if((FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
				&& (CopyTpBufferNumber > PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].CopyCompleteTpBufferNumber))
		{
			needClearTpBuffer = FALSE;
		}
	}
	return needClearTpBuffer;
}
/*copy the rx pdu data to the tp buffer*/
static FUNC(BufReq_ReturnType, PDUR_CODE)
PduR_CopyRxTpDataToTpBuffer(uint8 TpBufferId,P2CONST(PduInfoType, AUTOMATIC, PDUR_APPL_DATA) Info,P2VAR(PduLengthType, AUTOMATIC, PDUR_APPL_DATA) BufferSizePtr)
{
	BufReq_ReturnType bufQeqReturn;
	uint16 rxBufferOffset;
	uint8 nextValidTpBufferId;
	rxBufferOffset = PduR_TpBuffer[TpBufferId].RxBufferOffset;
	if(rxBufferOffset + Info->SduLength < PduR_TpBuffer[TpBufferId].TpBufferLength)
	{
		PduR_Memcpy(&PduR_TpBuffer[TpBufferId].TpBufferData[rxBufferOffset],Info->SduDataPtr,Info->SduLength);
		PduR_TpBuffer[TpBufferId].RxBufferOffset += Info->SduLength;
		*BufferSizePtr = PduR_TpBuffer[TpBufferId].TpBufferLength - PduR_TpBuffer[TpBufferId].RxBufferOffset;
		bufQeqReturn = BUFREQ_OK;
	}
	/*need another tp buffer to store the pdu(used for gateway-on-the-fly)*/
	else if(rxBufferOffset + Info->SduLength == PduR_TpBuffer[TpBufferId].TpBufferLength)
	{
		PduR_Memcpy(&PduR_TpBuffer[TpBufferId].TpBufferData[rxBufferOffset],Info->SduDataPtr,Info->SduLength);
		PduR_TpBuffer[TpBufferId].RxBufferOffset = PduR_TpBuffer[TpBufferId].TpBufferLength;
		/*find one unused tp buffer.if no unused tp buffer,return 0xff*/
		nextValidTpBufferId = PduR_FindNextValidTpBuffer();
		if(0xff != nextValidTpBufferId)
		{
			PduR_TpBuffer[TpBufferId].NextTpBufferId = nextValidTpBufferId;
			PduR_TpBuffer[nextValidTpBufferId].PduHandleId = PduR_TpBuffer[TpBufferId].PduHandleId;
			PduR_TpBuffer[nextValidTpBufferId].RxBufferOffset = 0;
			PduR_TpBuffer[nextValidTpBufferId].SduLength = PduR_TpBuffer[TpBufferId].SduLength;
			PduR_TpBuffer[nextValidTpBufferId].used = TRUE;
			*BufferSizePtr = PduR_TpBuffer[nextValidTpBufferId].TpBufferLength;
		}
		else
		{
			*BufferSizePtr = 0;
		}
		bufQeqReturn = BUFREQ_OK;
	}
	/*need another tp buffer to store the pdu(used for gateway-on-the-fly)*/
	else
	{
		/*find one unused tp buffer.if no unused tp buffer,return 0xff*/
		nextValidTpBufferId = PduR_FindNextValidTpBuffer();
		if(0xff != nextValidTpBufferId)
		{
			uint16 nextTpBufferStoreLength;
			nextTpBufferStoreLength = Info->SduLength - (PduR_TpBuffer[TpBufferId].TpBufferLength - rxBufferOffset);
			PduR_Memcpy(&PduR_TpBuffer[TpBufferId].TpBufferData[rxBufferOffset],Info->SduDataPtr,Info->SduLength - nextTpBufferStoreLength);
			PduR_TpBuffer[TpBufferId].RxBufferOffset = PduR_TpBuffer[TpBufferId].TpBufferLength;
			PduR_TpBuffer[TpBufferId].NextTpBufferId = nextValidTpBufferId;
			PduR_Memcpy(&PduR_TpBuffer[nextValidTpBufferId].TpBufferData[0],&Info->SduDataPtr[Info->SduLength - nextTpBufferStoreLength],nextTpBufferStoreLength);
			PduR_TpBuffer[nextValidTpBufferId].RxBufferOffset = nextTpBufferStoreLength;
			PduR_TpBuffer[nextValidTpBufferId].PduHandleId = PduR_TpBuffer[TpBufferId].PduHandleId;
			PduR_TpBuffer[nextValidTpBufferId].SduLength = PduR_TpBuffer[TpBufferId].SduLength;
			PduR_TpBuffer[nextValidTpBufferId].used = TRUE;
			*BufferSizePtr = PduR_TpBuffer[nextValidTpBufferId].TpBufferLength - nextTpBufferStoreLength;
			bufQeqReturn = BUFREQ_OK;
		}
		else
		{
			bufQeqReturn = BUFREQ_E_NOT_OK;
		}
	}

	return bufQeqReturn;
}
/*find one unused tp buffer.if no unused tp buffer,return 0xff*/
static FUNC(uint8, PDUR_CODE)
PduR_FindNextValidTpBuffer(void)
{
	uint8 tpBufferIndex;
	uint8 findTpBuffer = 0xff;
#if (0u < PDUR_TP_BUFFER_SUM)
	for(tpBufferIndex = 0u;tpBufferIndex < PDUR_TP_BUFFER_SUM;tpBufferIndex++)
	{
		if(FALSE == PduR_TpBuffer[tpBufferIndex].used)
		{
			findTpBuffer = tpBufferIndex;
		}
	}
#endif
	return findTpBuffer;
}
/*gateway MF pdu to Tp mode by LoTp_Transmit*/
static FUNC(boolean, PDUR_CODE)
PduR_GateWayMFToTp(uint16 PduRSrcPduId,uint16 PduRDestPduId)
{
	Std_ReturnType loTpTxReturn = E_NOT_OK;
	PduIdType gatewayTpRunTimeId;
	uint8 destModuleIndex;
	uint8 destModule;
	PduIdType loPduId;
	uint8 tpBufferId;
	PduInfoType pduRInfo;
	destModuleIndex = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].BswModuleIndex;
	destModule = PduR_BswModuleConfigData[destModuleIndex].PduRBswModuleRef;
	loPduId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].PduRDestModulePduIndex;
	gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].GateWayTpRunTimeIndex;
	tpBufferId = PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId;
	if(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
	{
		pduRInfo.SduLength = PduR_TpBuffer[tpBufferId].SduLength;
		#if(STD_ON == PDUR_META_DATA_SUPPORT)
		if(PduR_ConfigStd->PduRSrcPduRef[PduRSrcPduId].MetaDataLength > 0)
		{
			pduRInfo.SduDataPtr = PduR_TpBuffer[tpBufferId].MetaData;
		}
		else
		{
			pduRInfo.SduDataPtr = NULL_PTR;
		}
		#else
		pduRInfo.SduDataPtr = NULL_PTR;
		#endif
		switch(destModule)
		{
			#if(STD_ON == PDUR_CANTP_SUPPORT)
			case PDUR_CANTP:
				loTpTxReturn = CanTp_Transmit(loPduId,&pduRInfo);
				break;
			#endif
			#if(STD_ON == PDUR_J1939TP_SUPPORT)
			case PDUR_J1939TP:
				loTpTxReturn = J1939Tp_Transmit(loPduId,&pduRInfo);
				break;
			#endif
			default:
				break;
		}
	}
	return loTpTxReturn;
}
/*gateway SF pdu to Tp mode by LoTp_Transmit*/
static FUNC(Std_ReturnType, PDUR_CODE)
PduR_GateWaySFToTp(uint16 PduRSrcPduId,uint16 PduRDestPduId)
{
	Std_ReturnType loTpTxReturn;
	PduIdType gatewayTpRunTimeId;
	uint8 destModuleIndex;
	uint8 destModule;
	PduIdType loPduId;
	uint16 txBufferId;
	PduInfoType pduRInfo;
	destModuleIndex = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].BswModuleIndex;
	destModule = PduR_BswModuleConfigData[destModuleIndex].PduRBswModuleRef;
	loPduId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].PduRDestModulePduIndex;
	txBufferId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].PduRDestTxBufferRef;
	gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].GateWayTpRunTimeIndex;
	if(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
	{
		pduRInfo.SduLength = PduR_TxBuffer[txBufferId].PduRTxBufferRef[0].SduLength;
		#if(STD_ON == PDUR_META_DATA_SUPPORT)
		if(PduR_ConfigStd->PduRSrcPduRef[PduRSrcPduId].MetaDataLength > 0)
		{
			pduRInfo.SduDataPtr = PduR_TxBuffer[txBufferId].PduRTxBufferRef[0].MetaData;
		}
		else
		{
			pduRInfo.SduDataPtr = NULL_PTR;
		}
		#else
		pduRInfo.SduDataPtr = NULL_PTR;
		#endif
		switch(destModule)
		{
            #if(STD_ON == PDUR_CANTP_SUPPORT)
			case PDUR_CANTP:
				loTpTxReturn = CanTp_Transmit(loPduId,&pduRInfo);
				break;
            #endif
            #if(STD_ON == PDUR_J1939TP_SUPPORT)
			case PDUR_J1939TP:
				loTpTxReturn = J1939Tp_Transmit(loPduId,&pduRInfo);
				break;
            #endif
			default:
				break;
		}
	}
	return loTpTxReturn;
}
/*SF Tp pdu 1:n(n>1) route:route the pdu to one up mode*/
static FUNC(void, PDUR_CODE)
PduR_RouteSFtoUp(uint8 DestModule,uint16 PduRSrcPduId,uint16 PduRDestPduId)
{
	BufReq_ReturnType upModuleReturn;
	PduIdType upPduId;
	PduIdType gatewayTpRunTimeId;
	uint16 txBufferId;
	PduLengthType bufferLength;
	PduLengthType tpSduLength;
	PduInfoType pduRInfo;
	upPduId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].PduRDestModulePduIndex;
	gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].GateWayTpRunTimeIndex;
	txBufferId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].PduRDestTxBufferRef;
	#if(STD_ON == PDUR_META_DATA_SUPPORT)
	if(PduR_ConfigStd->PduRSrcPduRef[PduRSrcPduId].MetaDataLength > 0)
	{
		pduRInfo.SduDataPtr = PduR_TxBuffer[txBufferId].PduRTxBufferRef[0].MetaData;
		pduRInfo.SduLength = PduR_ConfigStd->PduRSrcPduRef[PduRSrcPduId].MetaDataLength;
	}
	else
	{
		pduRInfo.SduDataPtr = NULL_PTR;
		pduRInfo.SduLength = 0;
	}
	#else
	pduRInfo.SduDataPtr = NULL_PTR;
	pduRInfo.SduLength = 0;
    #endif
    tpSduLength = PduR_TxBuffer[txBufferId].PduRTxBufferRef[0].SduLength;
    switch(DestModule)
    {
        #if(STD_ON == PDUR_COM_SUPPORT)
        case PDUR_COM:
        	upModuleReturn = Com_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
        	if((BUFREQ_OK == upModuleReturn) && (bufferLength >= tpSduLength))
        	{
        		pduRInfo.SduDataPtr = PduR_TxBuffer[txBufferId].PduRTxBufferRef[0].TxBufferData;
        		pduRInfo.SduLength = tpSduLength;
        		upModuleReturn = Com_CopyRxData(upPduId,&pduRInfo,&bufferLength);
        		if(BUFREQ_OK == upModuleReturn)
        		{
        			Com_TpRxIndication(upPduId,E_OK);
        		}
        		else
        		{
        			Com_TpRxIndication(upPduId,E_NOT_OK);
        		}
        	}
        	PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
        	break;
        #endif
		#if(STD_ON == PDUR_LDCOM_SUPPORT)
		case PDUR_LDCOM:
			upModuleReturn = LdCom_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
			if((BUFREQ_OK == upModuleReturn) && (bufferLength >= tpSduLength))
			{
				pduRInfo.SduDataPtr = PduR_TxBuffer[txBufferId].PduRTxBufferRef[0].TxBufferData;
				pduRInfo.SduLength = tpSduLength;
				upModuleReturn = LdCom_CopyRxData(upPduId,&pduRInfo,&bufferLength);
				if(BUFREQ_OK == upModuleReturn)
				{
					LdCom_TpRxIndication(upPduId,E_OK);
				}
				else
				{
					LdCom_TpRxIndication(upPduId,E_NOT_OK);
				}
			}
			PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
			break;
		#endif
		#if(STD_ON == PDUR_SECOC_SUPPORT)
		case PDUR_SECOC:
			upModuleReturn = SecOC_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
			if((BUFREQ_OK == upModuleReturn) && (bufferLength >= tpSduLength))
			{
				pduRInfo.SduDataPtr = PduR_TxBuffer[txBufferId].PduRTxBufferRef[0].TxBufferData;
				pduRInfo.SduLength = tpSduLength;
				upModuleReturn = SecOC_CopyRxData(upPduId,&pduRInfo,&bufferLength);
				if(BUFREQ_OK == upModuleReturn)
				{
					SecOC_TpRxIndication(upPduId,E_OK);
				}
				else
				{
					SecOC_TpRxIndication(upPduId,E_NOT_OK);
				}
			}
			PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
			break;
		#endif
        #if(STD_ON == PDUR_DCM_SUPPORT)
        case PDUR_DCM:
        	upModuleReturn = Dcm_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
        	if((BUFREQ_OK == upModuleReturn) && (bufferLength >= tpSduLength))
        	{
        		pduRInfo.SduDataPtr = PduR_TxBuffer[txBufferId].PduRTxBufferRef[0].TxBufferData;
        		pduRInfo.SduLength = tpSduLength;
        		upModuleReturn = Dcm_CopyRxData(upPduId,&pduRInfo,&bufferLength);
        		if(BUFREQ_OK == upModuleReturn)
        		{
        			Dcm_TpRxIndication(upPduId,E_OK);
        		}
        		else
        		{
        			Dcm_TpRxIndication(upPduId,E_NOT_OK);
        		}
        	}
        	PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
        	break;
		#endif
		#if(STD_ON == PDUR_J1939DCM_SUPPORT)
        case PDUR_J1939DCM:
        	upModuleReturn = J1939Dcm_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
        	if((BUFREQ_OK == upModuleReturn) && (bufferLength >= tpSduLength))
        	{
        		pduRInfo.SduDataPtr = PduR_TxBuffer[txBufferId].PduRTxBufferRef[0].TxBufferData;
        		pduRInfo.SduLength = tpSduLength;
        		upModuleReturn = J1939Dcm_CopyRxData(upPduId,&pduRInfo,&bufferLength);
        		if(BUFREQ_OK == upModuleReturn)
        		{
        			J1939Dcm_TpRxIndication(upPduId,E_OK);
        		}
        		else
        		{
        			J1939Dcm_TpRxIndication(upPduId,E_NOT_OK);
        		}
        	}
        	PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
        	break;
        #endif
        default:
        	break;
    }
	return ;
}
/*MF Tp pdu 1:n(n>1) route:route the pdu to one up mode*/
static FUNC(void, PDUR_CODE)
PduR_RouteMFtoUp(uint8 DestModule,uint16 PduRSrcPduId,uint16 PduRDestPduId)
{
	BufReq_ReturnType upModuleReturn;
	PduIdType upPduId;
	PduIdType gatewayTpRunTimeId;
	uint16 tpBufferId;
	PduLengthType bufferLength;
	PduLengthType tpSduLength;
	PduInfoType pduRInfo;
	uint16 routeOffset;
	upPduId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].PduRDestModulePduIndex;
	gatewayTpRunTimeId = PduR_ConfigStd->PduRDestPduRef[PduRDestPduId].GateWayTpRunTimeIndex;
	tpBufferId = PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].ActiveTpBufferId;
	#if(STD_ON == PDUR_META_DATA_SUPPORT)
	if(PduR_ConfigStd->PduRSrcPduRef[PduRSrcPduId].MetaDataLength > 0)
	{
		pduRInfo.SduDataPtr = PduR_TpBuffer[tpBufferId].MetaData;
		pduRInfo.SduLength = PduR_ConfigStd->PduRSrcPduRef[PduRSrcPduId].MetaDataLength;
	}
	else
	{
		pduRInfo.SduDataPtr = NULL_PTR;
		pduRInfo.SduLength = 0;
	}
	#else
	pduRInfo.SduDataPtr = NULL_PTR;
	pduRInfo.SduLength = 0;
    #endif
    tpSduLength = PduR_TpBuffer[tpBufferId].SduLength;
    switch(DestModule)
    {
        #if(STD_ON == PDUR_COM_SUPPORT)
        case PDUR_COM:
        	upModuleReturn = Com_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
        	routeOffset = 0;
        	if((BUFREQ_OK != upModuleReturn) || (bufferLength == 0))
        	{
        		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
        	}
        	while(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
        	{
				pduRInfo.SduDataPtr = &(PduR_TpBuffer[tpBufferId].TpBufferData[routeOffset]);
				if(bufferLength > (tpSduLength - routeOffset))
				{
					pduRInfo.SduLength = tpSduLength - routeOffset;
				}
				else
				{
					pduRInfo.SduLength = bufferLength;
				}
				upModuleReturn = Com_CopyRxData(upPduId,&pduRInfo,&bufferLength);
				if((BUFREQ_OK == upModuleReturn) && (bufferLength != 0))
				{
					routeOffset += pduRInfo.SduLength;
					if(routeOffset == tpSduLength)
					{
						Com_TpRxIndication(upPduId,E_OK);
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
					}
				}
				else
				{
					Com_TpRxIndication(upPduId,E_NOT_OK);
					PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
				}
        	}
        	break;
		#endif
		#if(STD_ON == PDUR_LDCOM_SUPPORT)
		case PDUR_LDCOM:
			upModuleReturn = LdCom_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
			routeOffset = 0;
			if((BUFREQ_OK != upModuleReturn) || (bufferLength == 0))
			{
				PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
			}
			while(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
			{
				pduRInfo.SduDataPtr = &(PduR_TpBuffer[tpBufferId].TpBufferData[routeOffset]);
				if(bufferLength > (tpSduLength - routeOffset))
				{
					pduRInfo.SduLength = tpSduLength - routeOffset;
				}
				else
				{
					pduRInfo.SduLength = bufferLength;
				}
				upModuleReturn = LdCom_CopyRxData(upPduId,&pduRInfo,&bufferLength);
				if((BUFREQ_OK == upModuleReturn) && (bufferLength != 0))
				{
					routeOffset += pduRInfo.SduLength;
					if(routeOffset == tpSduLength)
					{
						LdCom_TpRxIndication(upPduId,E_OK);
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
					}
				}
				else
				{
					LdCom_TpRxIndication(upPduId,E_NOT_OK);
					PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
				}
			}
			break;
		#endif
		#if(STD_ON == PDUR_SECOC_SUPPORT)
		case PDUR_SECOC:
			upModuleReturn = SecOC_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
			routeOffset = 0;
			if((BUFREQ_OK != upModuleReturn) || (bufferLength == 0))
			{
				PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
			}
			while(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
			{
				pduRInfo.SduDataPtr = &(PduR_TpBuffer[tpBufferId].TpBufferData[routeOffset]);
				if(bufferLength > (tpSduLength - routeOffset))
				{
					pduRInfo.SduLength = tpSduLength - routeOffset;
				}
				else
				{
					pduRInfo.SduLength = bufferLength;
				}
				upModuleReturn = SecOC_CopyRxData(upPduId,&pduRInfo,&bufferLength);
				if((BUFREQ_OK == upModuleReturn) && (bufferLength != 0))
				{
					routeOffset += pduRInfo.SduLength;
					if(routeOffset == tpSduLength)
					{
						SecOC_TpRxIndication(upPduId,E_OK);
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
					}
				}
				else
				{
					SecOC_TpRxIndication(upPduId,E_NOT_OK);
					PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
				}
			}
			break;
		#endif
		#if(STD_ON == PDUR_DCM_SUPPORT)
        case PDUR_DCM:
        	upModuleReturn = Dcm_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
        	routeOffset = 0;
        	if((BUFREQ_OK != upModuleReturn) || (bufferLength == 0))
        	{
        		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
        	}
        	while(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
        	{
				pduRInfo.SduDataPtr = &(PduR_TpBuffer[tpBufferId].TpBufferData[routeOffset]);
				if(bufferLength > (tpSduLength - routeOffset))
				{
					pduRInfo.SduLength = tpSduLength - routeOffset;
				}
				else
				{
					pduRInfo.SduLength = bufferLength;
				}
				upModuleReturn = Dcm_CopyRxData(upPduId,&pduRInfo,&bufferLength);
				if((BUFREQ_OK == upModuleReturn) && (bufferLength != 0))
				{
					routeOffset += pduRInfo.SduLength;
					if(routeOffset == tpSduLength)
					{
						Dcm_TpRxIndication(upPduId,E_OK);
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
					}
				}
				else
				{
					Dcm_TpRxIndication(upPduId,E_NOT_OK);
					PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
				}
        	}
        	break;
		#endif
		#if(STD_ON == PDUR_J1939DCM_SUPPORT)
        case PDUR_J1939DCM:
        	upModuleReturn = J1939Dcm_StartOfReception(upPduId,&pduRInfo,tpSduLength,&bufferLength);
        	routeOffset = 0;
        	if((BUFREQ_OK != upModuleReturn) || (bufferLength == 0))
        	{
        		PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
        	}
        	while(FALSE == PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation)
        	{
				pduRInfo.SduDataPtr = &(PduR_TpBuffer[tpBufferId].TpBufferData[routeOffset]);
				if(bufferLength > (tpSduLength - routeOffset))
				{
					pduRInfo.SduLength = tpSduLength - routeOffset;
				}
				else
				{
					pduRInfo.SduLength = bufferLength;
				}
				upModuleReturn = J1939Dcm_CopyRxData(upPduId,&pduRInfo,&bufferLength);
				if((BUFREQ_OK == upModuleReturn) && (bufferLength != 0))
				{
					routeOffset += pduRInfo.SduLength;
					if(routeOffset == tpSduLength)
					{
						J1939Dcm_TpRxIndication(upPduId,E_OK);
						PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
					}
				}
				else
				{
					J1939Dcm_TpRxIndication(upPduId,E_NOT_OK);
					PduR_GateWayDestTpRTSate[gatewayTpRunTimeId].TpTxConfirmation = TRUE;
				}
        	}
        	break;
        #endif
        default:
        	break;
    }
	return ;
}
/*find one valid tp buffer.if not find,return 0xff*/
static FUNC(uint8, PDUR_CODE)
PduR_FindValidTpBuffer(uint16 PduRSrcPduId,uint16 PduLength)
{
	uint8 tpBufferIndex;
	uint8 findTpBuffer = 0xff;
#if (0u < PDUR_TP_BUFFER_SUM)
	for(tpBufferIndex = 0u;tpBufferIndex < PDUR_TP_BUFFER_SUM;tpBufferIndex++)
	{
		if((FALSE == PduR_TpBuffer[tpBufferIndex].used) && (PduLength <= PduR_TpBuffer[tpBufferIndex].TpBufferLength))
		{
			if(0xff == findTpBuffer)
			{
				findTpBuffer = tpBufferIndex;
			}
			else
			{
				if(PduR_TpBuffer[findTpBuffer].TpBufferLength > PduR_TpBuffer[tpBufferIndex].TpBufferLength)
				{
					findTpBuffer = tpBufferIndex;
				}
			}
		}
	}
#endif

	if((TRUE == PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].GatewayOnTheFly)
			&& (0xff == findTpBuffer))
	{
#if (0u < PDUR_TP_BUFFER_SUM)
		for(tpBufferIndex = 0u;(tpBufferIndex < PDUR_TP_BUFFER_SUM)&&(0xff == findTpBuffer);tpBufferIndex++)
		{
			if((PduR_ConfigStd->PduRRoutingTableRef[PduR_ConfigStd->PduRConfigId].PduRRoutingPathRef[PduRSrcPduId].PduRTpMaxThreshold <= PduR_TpBuffer[tpBufferIndex].TpBufferLength)
					&& (FALSE == PduR_TpBuffer[tpBufferIndex].used))
			{
				findTpBuffer = tpBufferIndex;
			}
		}
#endif
	}

	return findTpBuffer;
}
/*find the rx tp pdu active store tp buffer*/
static FUNC(uint8, PDUR_CODE)
PduR_FindTpBuffer(uint16 PduRSrcPduId)
{
	uint8 tpBufferId = 0xff;
#if (0u < PDUR_TP_BUFFER_SUM)
	uint8 cnt;
	for(cnt = 0u;cnt < PDUR_TP_BUFFER_SUM;cnt++)
	{
		if((TRUE == PduR_TpBuffer[cnt].used) && (PduRSrcPduId == PduR_TpBuffer[cnt].PduHandleId))
		{
			if(0xff == PduR_TpBuffer[cnt].NextTpBufferId)
			{
				tpBufferId = cnt;
			}
		}
	}
#endif
	return tpBufferId;
}
#endif/*STD_ON == PDUR_TP_SUPPORT*/
#define PDUR_STOP_SEC_CODE
#include "PduR_MemMap.h"

#endif/*STD_OFF == PDUR_ZERO_COST_OPERATION*/


